package com.itcam.cammyso.manager;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itcam.cammyso.common.ErrorCode;
import com.itcam.cammyso.datasource.*;
import com.itcam.cammyso.exception.BusinessException;
import com.itcam.cammyso.exception.ThrowUtils;
import com.itcam.cammyso.model.dto.post.PostQueryRequest;
import com.itcam.cammyso.model.dto.search.SearchQueryRequest;
import com.itcam.cammyso.model.dto.user.UserQueryRequest;
import com.itcam.cammyso.model.entity.Picture;
import com.itcam.cammyso.model.enums.SearchTypeEnum;
import com.itcam.cammyso.model.vo.PostVO;
import com.itcam.cammyso.model.vo.SearchVO;
import com.itcam.cammyso.model.vo.UserVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.CompletableFuture;

/**
 * @author : Cammy.Wu
 * Description : 门面模式
 * <p>
 * todo:门面模式：
 *      帮助我们用户（客户端）去更轻松地实现功能，不需要关心门面背后的细节
 *      聚合搜索类业务基本都是门面模式：即前端不用关心后端从哪里、怎么去取不同来源、怎么去聚合不同来源的数据，更方便地获取到内容。
 *    补充：当调用你系统（接口）的客户端觉得麻烦的时候，你就应该思考，是不是可以抽象一个门面了。
 */

@Component
@Slf4j
public class SearchFacade {

    @Resource
    private UserDataSource userDataSource;

    @Resource
    private PostDataSource postDataSource;

    @Resource
    private PictureDataSource pictureDataSource;

    @Resource
    private DataSourceRegistry dataSourceRegistry;

    public SearchVO searchAll(@RequestBody SearchQueryRequest searchQueryRequest, HttpServletRequest request) {
        String type = searchQueryRequest.getType();
        SearchTypeEnum searchTypeEnum = SearchTypeEnum.getEnumByValue(type);
        ThrowUtils.throwIf(StringUtils.isBlank(type), ErrorCode.PARAMS_ERROR);

        String searchText = searchQueryRequest.getSearchText();
        long current = searchQueryRequest.getCurrent();
        long pageSize = searchQueryRequest.getPageSize();

        if (searchTypeEnum == null) {
            // 使用并发
            CompletableFuture<Page<UserVO>> userTask = CompletableFuture.supplyAsync(() -> {
                UserQueryRequest userQueryRequest = new UserQueryRequest();
                userQueryRequest.setUserName(searchText);
                Page<UserVO> userVOPage = userDataSource.doSearch(searchText, current, pageSize);
                return userVOPage;
            });

            CompletableFuture<Page<PostVO>> postTask = CompletableFuture.supplyAsync(() -> {
                PostQueryRequest postQueryRequest = new PostQueryRequest();
                postQueryRequest.setSearchText(searchText);
                Page<PostVO> postVOPage = postDataSource.doSearch(searchText, current, pageSize);
                return postVOPage;
            });

            CompletableFuture<Page<Picture>> pictureTask = CompletableFuture.supplyAsync(() -> {
                Page<Picture> picturePage = pictureDataSource.doSearch(searchText, current, pageSize);
                return picturePage;
            });


            CompletableFuture.allOf(userTask, postTask, pictureTask).join();
            try {
                Page<UserVO> userVOPage = userTask.get();
                Page<PostVO> postVOPage = postTask.get();
                Page<Picture> picturePage = pictureTask.get();
                SearchVO searchVO = new SearchVO();
                searchVO.setUserList(userVOPage.getRecords());
                searchVO.setPostList(postVOPage.getRecords());
                searchVO.setPictureList(picturePage.getRecords());
                return searchVO;
            } catch (Exception e) {
                log.error("查询异常", e);
                throw new BusinessException(ErrorCode.SYSTEM_ERROR, "查询异常");
            }
        } else {
            // 注册器模式
            SearchVO searchVO = new SearchVO();
            DataSource<?> dataSource = dataSourceRegistry.getDataSourceByType(type);
            Page<?> page = dataSource.doSearch(searchText, current, pageSize);
            searchVO.setDataList(page.getRecords());
            return searchVO;

//            2.0
//            Map<String, DataSource<T>> typeDataSourceMap = new HashMap() {{
//                put(SearchTypeEnum.POST.getValue(), postDataSource);
//                put(SearchTypeEnum.USER.getValue(), userDataSource);
//                put(SearchTypeEnum.PICTURE.getValue(), pictureDataSource);
//            }};
//            SearchVO searchVO = new SearchVO();
//            DataSource<?> dataSource = typeDataSourceMap.get(type);
//            Page<?> page = dataSource.doSearch(searchText, current, pageSize);
//            searchVO.setDataList(page.getRecords());
//            return searchVO;

//            1.0
//            SearchVO searchVO = new SearchVO();
//            switch (searchTypeEnum) {
//                case POST:
//                    PostQueryRequest postQueryRequest = new PostQueryRequest();
//                    postQueryRequest.setSearchText(searchText);
//                    Page<PostVO> postVOPage = postService.listPostVOByPage(postQueryRequest, request);
//                    searchVO.setPostList(postVOPage.getRecords());
//                    break;
//                case USER:
//                    UserQueryRequest userQueryRequest = new UserQueryRequest();
//                    userQueryRequest.setUserName(searchText);
//                    Page<UserVO> userVOPage = userService.listUserVOByPage(userQueryRequest);
//                    searchVO.setUserList(userVOPage.getRecords());
//                    break;
//                case PICTURE:
//                    Page<Picture> picturePage = pictureService.searchPicture(searchText, 1, 10);
//                    searchVO.setPictureList(picturePage.getRecords());
//                    break;
//                default:
//                    break;
//            }
//            return searchVO;
        }
    }
}
